import { NextRequest, NextResponse } from 'next/server';
import { GloableResponseItem, ResponseEnum } from '@/utils/request/res';
import { Auth, DbScheme, type ExtendedNextApiRequest, LogOperation, ResponseHandler } from '@/utils/decorator';
import prisma from '@/utils/db/PrismaService';

import { BaseController } from '@/utils/request/BaseController';
import { getCurrentTimeInShanghai } from '@/utils';
import { createRoleSchema, updateRoleSchema } from '@/dbSchema/systemSchema';
import { GET as HttpGet, POST as HttpPost, PUT as HttpPut, DELETE as HttpDelete } from '@/utils/decorator';
import { createAllMethodHandlers } from '@/utils/request/routeRegistry';
import { Prisma } from '@prisma/client';

class SystemRbacController extends BaseController {
    /**
     * 新增角色
     */
    @Auth()
    @ResponseHandler()
    @HttpPost()
    @DbScheme(createRoleSchema)
    @LogOperation({
        module: "角色管理",
        operationName: "添加角色"
    })
    static async addRole(request: ExtendedNextApiRequest) {
        const { role_name, role_key, status, description, permissions } = request.customBody;

        const existingRole = await prisma.sysRole.findFirst({
            where: { role_key: role_key, del_flag: 1 },
        });

        if (existingRole) {
            return GloableResponseItem(ResponseEnum.fail, '角色标识已存在', null);
        }

        const currentTime = getCurrentTimeInShanghai();
        const dataToCreate = {
            role_name,
            role_key,
            status,
            description,
            create_time: currentTime,
            update_time: currentTime,
        };

        try {
            const newRole = await prisma.sysRole.create({
                data: dataToCreate,
            });

            if (permissions && permissions.length > 0) {
                await prisma.sysRolePermissionLink.createMany({
                    data: permissions.map((permissionId: number) => ({
                        role_id: newRole.id,
                        permission_id: permissionId,
                    })),
                });
            }

            return GloableResponseItem(ResponseEnum.success, '角色添加成功', newRole);
        } catch (error) {
            console.error('添加角色失败:', error);
            return GloableResponseItem(ResponseEnum.fail, '角色添加失败', null);
        }
    }

    /**
     * 获取角色列表
     */
    @Auth()
    @ResponseHandler()
    @HttpGet()
    static async getRoleList(request: ExtendedNextApiRequest) {
        const params = request.customBody;
        const page = parseInt(params?.page || '1');
        const pageSize = parseInt(params?.pageSize || '10');
        const skip = (page - 1) * pageSize;

        const where: Prisma.SysRoleWhereInput = {
            del_flag: 1,
            ...(params?.role_name && { role_name: { contains: params.role_name } }),
            ...(params?.role_key && { role_key: { contains: params.role_key } }),
            ...(params?.status && { status: parseInt(params.status) }),
        };

        try {
            const [roles, total] = await prisma.$transaction([
                prisma.sysRole.findMany({
                    where,
                    include: {
                        permissions: {
                            select: {
                                permission_id: true,
                            },
                        },
                    },
                    orderBy: { update_time: 'desc' },
                    skip,
                    take: pageSize,
                }),
                prisma.sysRole.count({ where }),
            ]);

            const formatData = roles.map(role => ({
                ...role,
                key: role.id,
                permissions: role.permissions.map(p => p.permission_id),
            }));

            return GloableResponseItem(ResponseEnum.success, '', {
                data: formatData || [],
                total: total,
                page,
                pageSize,
            });
        } catch (error) {
            console.error('获取角色列表失败:', error);
            return GloableResponseItem(ResponseEnum.fail, '获取角色列表失败', null);
        }
    }

    /**
     * 获取所有可用角色列表
     */
    @Auth()
    @ResponseHandler()
    @HttpGet()
    static async getAllRoles() {
        try {
            const roles = await prisma.sysRole.findMany({
                where: {
                    del_flag: 1, // 未删除
                    status: 1,   // 已启用
                },
                select: {
                    id: true,
                    role_name: true,
                    role_key: true,
                },
                orderBy: {
                    update_time: 'desc'
                }
            });

            const formattedRoles = roles.map(role => ({
                value: role.id,
                label: role.role_name,
                key: role.role_key
            }));

            return GloableResponseItem(ResponseEnum.success, '获取所有角色成功', formattedRoles);
        } catch (error) {
            console.error('获取所有角色失败:', error);
            return GloableResponseItem(ResponseEnum.fail, '获取所有角色失败', null);
        }
    }

    /**
     * 获取所有权限列表
     */
    @Auth()
    @ResponseHandler()
    @HttpGet()
    static async getPermissionList() {
        try {
            const permissions = await prisma.sysDict.findMany({
                where: { dict_type: 'sys_permission', del_flag: 1 },
                select: { id: true, dict_name: true, description: true },
            });

            const formattedPermissions = permissions.map(p => ({
                value: p.id,
                label: p.dict_name,
                description: p.description,
            }));

            return GloableResponseItem(ResponseEnum.success, '获取权限列表成功', formattedPermissions);
        } catch (error) {
            console.error('获取权限列表失败:', error);
            return GloableResponseItem(ResponseEnum.fail, '获取权限列表失败', null);
        }
    }

    /**
     * 更新角色
     */
    @Auth()
    @ResponseHandler()
    @HttpPut()
    @DbScheme(updateRoleSchema)
    @LogOperation({
        module: "角色管理",
        operationName: "更新角色"
    })
    static async updateRole(request: ExtendedNextApiRequest) {
        const { id, permissions,action,key, ...roleData } = request.customBody;

        try {
            await prisma.$transaction(async (tx) => {
                await tx.sysRole.update({
                    where: { id },
                    data: {
                        ...roleData,
                        update_time: getCurrentTimeInShanghai(),
                    },
                });

                await tx.sysRolePermissionLink.deleteMany({
                    where: { role_id: id },
                });

                if (permissions && permissions.length > 0) {
                    await tx.sysRolePermissionLink.createMany({
                        data: permissions.map((permissionId: number) => ({
                            role_id: id,
                            permission_id: permissionId,
                        })),
                    });
                }
            });

            return GloableResponseItem(ResponseEnum.success, '角色更新成功', null);
        } catch (error) {
            console.error('更新角色失败:', error);
            if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === 'P2025') {
                return GloableResponseItem(ResponseEnum.fail, '角色不存在', null);
            }
            return GloableResponseItem(ResponseEnum.fail, '角色更新失败', null);
        }
    }

    /**
     * 删除角色（软删除）
     */
    @Auth()
    @ResponseHandler()
    @HttpDelete()
    @LogOperation({
        module: "角色管理",
        operationName: "删除角色"
    })
    static async deleteRole(request: ExtendedNextApiRequest) {
        const { id } = request.customBody;

        try {
            await prisma.sysRole.update({
                where: { id },
                data: { del_flag: 0, update_time: getCurrentTimeInShanghai() },
            });
            return GloableResponseItem(ResponseEnum.success, '角色删除成功', null);
        } catch (error) {
            console.error('删除角色失败:', error);
            if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === 'P2025') {
                return GloableResponseItem(ResponseEnum.fail, '角色不存在', null);
            }
            return GloableResponseItem(ResponseEnum.fail, '角色删除失败', null);
        }
    }
}

const handlers = createAllMethodHandlers(SystemRbacController);
export const GET = handlers.GET;
export const POST = handlers.POST;
export const PUT = handlers.PUT;
export const DELETE = handlers.DELETE; 